package me.lensfrex.trailblazer.api.v1.service.register;

import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import me.lensfrex.trailblazer.api.v1.beans.requests.RegisterRequestBody;
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ResponseCode;
import me.lensfrex.trailblazer.api.v1.beans.responses.RegisterResponseData;
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ResponseBase;
import me.lensfrex.trailblazer.api.v1.dao.UserDao;
import me.lensfrex.trailblazer.api.v1.exceptions.RequestDataInvalidException;
import me.lensfrex.trailblazer.api.v1.utils.InputChecker;
import me.lensfrex.trailblazer.api.v1.utils.jwt.JWTManager;
import org.mindrot.jbcrypt.BCrypt;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.UUID;

@Path("/register")
public class Register {
    private static final JWTManager jwtManager = JWTManager.getInstance();
    private static final Gson gson = new Gson();

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String register(String request) {
        RegisterRequestBody registerRequestBody;

        try {
            registerRequestBody = gson.fromJson(request, RegisterRequestBody.class);

            if (registerRequestBody == null ||
                    InputChecker.hasInvalidChar(registerRequestBody.getUserName()) ||
                    InputChecker.hasInvisibleChar(registerRequestBody.getPassword())) {

                throw new RequestDataInvalidException();
            }

            if (UserDao.isUserAlreadyExist(registerRequestBody.getUserName())) {
                return gson.toJson(ResponseBase.error(ResponseCode.USER_ALREADY_EXISTS, "申请注册的用户已经存在"));
            }

            String userUUID = UUID.randomUUID().toString();
            String userBcryptPasswd = BCrypt.hashpw(registerRequestBody.getPassword(), BCrypt.gensalt());

            int newUid = UserDao.addUser(userUUID, registerRequestBody.getUserName(), userBcryptPasswd);

            Date expireDate = Date.from(Instant.now().plus(JWTManager.TOKEN_DEFAULT_EXPIRE_DAY, ChronoUnit.DAYS));
            RegisterResponseData registerResponseBody = new RegisterResponseData(
                    newUid,
                    userUUID,
                    jwtManager.createNewJWT(registerRequestBody.getUserName(), expireDate),
                    expireDate.getTime());

            return gson.toJson(ResponseBase.success(registerResponseBody));
        } catch (JsonParseException | RequestDataInvalidException e) {
            return gson.toJson(ResponseBase.error(ResponseCode.REQUEST_FORMAT_INVALID, "请求的数据不正确"));
        } catch (Exception e) {
            return gson.toJson(ResponseBase.error(ResponseCode.SERVER_ERROR, "服务器程序发生错误，有个家伙又写bug了。Error:" + e.getMessage()));
        }
    }
}